/*! Copyright(c) 2008-2012
 *
 *\file		Stm8s_gpio.c
 *\brief		
 *\details	
 *
 *\author	Cai Peifeng
 *\version	
 *\date		09May12
 *
 *\warning	
 *
 *\history \arg	09May12, Cai Peifeng, Create the file
 */
#include "Stm8s_gpio.h"


/*!
 *\fn			void GPIO_DeInit(GPIO_TypeDef* GPIOx);
 *\brief   		Deinitializes the GPIOx peripheral registers to their default reset values.
 *
 *\param[in]	GPIOx: Select the GPIO peripheral number (x = A to I).   
 *\param[out]  	N/A
 *
 *\return  		N/A
 *\retval  		N/A
 *
 *\note		  
 */
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
	GPIOx->ODR = GPIO_ODR_RESET_VALUE;
	GPIOx->DDR = GPIO_DDR_RESET_VALUE;
	GPIOx->CR1 = GPIO_CR1_RESET_VALUE;
	GPIOx->CR2 = GPIO_CR2_RESET_VALUE;
}

/*!
 *\fn			void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
{
	assert_param(IS_GPIO_PIN_OK(GPIO_Mode));
	assert_param(IS_GPIO_PIN_OK(GPIO_Pin))
		;
	/* Reset corresponding bit to GPIO_Pin in CR2 register */
	GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));

	if(((uint8_t)(GPIO_Mode) & GPIO_MODE_OUT) != (uint8_t)0x00)
	{
		if(((uint8_t)(GPIO_Mode) & (uint8_t)GPIO_MODE_HIGH) != (uint8_t)0x00)
		{
			GPIOx->ODR |= (uint8_t)GPIO_Pin;
		}
		else
		{
			GPIOx->ODR &= (uint8_t)(~(GPIO_Pin));
		}
        /* Set Output mode */
        GPIOx->DDR |= (uint8_t)GPIO_Pin;		
	}
	else
	{
		GPIOx->DDR &= (uint8_t)(~(GPIO_Pin));
	}

	if( (((uint8_t)(GPIO_Mode)) & (uint8_t)GPIO_MODE_PULLUP) != (uint8_t)0x00)
	{
		GPIOx->CR1 |= (uint8_t)GPIO_Pin;
	}
	else
	{
		GPIOx->CR1 &= (uint8_t)(~(GPIO_Pin));
	}


	if((( (uint8_t)(GPIO_Mode) & (uint8_t)GPIO_MODE_INTERRUPT ) != (uint8_t)0x00))
	{
		GPIOx->CR2 |= (uint8_t)GPIO_Pin;
	}
	else
	{
		GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
	}
}

/*!
 *\fn			void GPIO_Write(GPIO_TypeDef* GPIOx, uint8_t PortVal);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void GPIO_Write(GPIO_TypeDef* GPIOx, uint8_t PortVal)
{
	GPIOx->ODR = PortVal;
}


/*!
 *\fn			void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
{
	GPIOx->ODR |= (uint8_t)PortPins;
}


/*!
 *\fn			void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
{
    GPIOx->ODR &= (uint8_t)(~PortPins);	
}

/*!
 *\fn			void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
{
	GPIOx->ODR ^= (uint8_t)PortPins;
}

/*!
 *\fn			uint8_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
uint8_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
	return (uint8_t)(GPIOx->IDR);
}


/*!
 *\fn			uint8_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
uint8_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
{
	return (uint8_t)(GPIOx->ODR);
}

/*!
 *\fn			BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)
{
    return ((BitStatus)(GPIOx->IDR & (uint8_t)GPIO_Pin));
}

/*!
 *\fn			void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState);
 *\brief   
 *
 *\param[in]   
 *\param[out]  
 *
 *\return  
 *\retval  
 *
 *\note		  
 */
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState)
{
	assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
	assert_param(IS_FUNCTIONALSTATE_OK(NewState));

    if (NewState != DISABLE) /* External Pull-Up Set*/
    {
        GPIOx->CR1 |= (uint8_t)GPIO_Pin;
    }
	else /* External Pull-Up Reset*/
    {
        GPIOx->CR1 &= (uint8_t)(~(GPIO_Pin));
    }	
}
